Fundamentals of Unity UI

译文

Fundamentals of Unity UI
Unity UI基础知识

版本检查: 2017.3
难度: 高级

It is important to understand the different parts making up the Unity UI system. There are several fundamental classes and components that, together, compose the system. This chapter first defines a number of terms used throughout this series of articles, then discusses the low-level behavior of several of Unity UI's key systems.
理解构成Unity UI系统的每个部分是很重要的。有几个基本类和组件一起组成系统。本章首先定义了本系列文章中使用的一些术语,然后讨论了几个Unity UI关键系统的低级行为。

Terminology
术语

A Canvas is a native-code Unity component that is used by Unity’s rendering system to provide layered geometry that will be drawn in, or on top of, a game’s world-space.
画布(Canvas)是一个unity原生组件,它被用来给unity的渲染系统提供可分层的几何图形,这些图形将会被绘制在游戏的世界空间中。

Canvases are responsible for combining their constituent geometry into batches, generating the appropriate render commands and sending these to Unity’s Graphics system. All of this is done in native C++ code, and is called a rebatch or a batch build. When a Canvas has been marked as containing geometry that requires rebatching, the Canvas is considered dirty.
画布负责将组成它的几何图形结合起来形成批次,生成合适的渲染命令并将这些命令发送到Unity的图形系统。这些都是在本机C ++代码中完成的,称为重新构建或批量构建。当一块画布所包含几何图形需要重新构建的时候,这个画布就被视为dirty。

Geometry is provided to Canvases by Canvas Renderer components.
几何图形通过Canvas Renderer组件提供给画布。

A Sub-canvas is simply a Canvas component that is nested inside another Canvas component. Sub-canvases isolate their children from their parent; a dirty child will not force a parent to rebuild its geometry, and vice versa. There are certain edge cases where this is not true, such as when changes to a parent Canvas cause a child Canvas to be resized.
子画布仅仅是一个嵌套在另一个画布中的画布组件。子画布将他的子物体和父物体隔离开来; dirty的子物体是不会强迫它的父物体去重新构建它的几何图形,反之亦然。还有一些特殊的情况,例如,对父画布的更改会导致子画布的大小发生改变。

A Graphic is a base class provided by the Unity UI C# library. It is the base class for all Unity UI C# classes that provide drawable geometry to the Canvas system. Most built-in Unity UI Graphics are implemented via the MaskableGraphic subclass, which allows them to be masked via the IMaskable interface. The major subclasses of Drawable are Image and Text, which provide their eponymous components.
图形(Graphic )是Unity UI C#库提供的基类。它是所有Unitiy UI C#类的基类,它给画布系统提供了可绘制几何图形的功能。大部分的内置Unity UI图形都是通过MaskableGraphic子类实现的,它允许通过IMaskable接口对它们进行屏蔽。Drawable的主要子类是ImageText,它们提供了同名组件。

Layout components control the size and positioning of RectTransforms, and are generally used to create complex layouts that require relative sizing or relative positioning of their contents. Layout components rely only on RectTransforms and only affect the properties of their associated RectTransforms. They are not dependent on the Graphic class, and can be used independently from Unity UI’s Graphic components.
布局组件控制RectTransforms的大小和位置,通常用来创建需要关联内容尺寸大小或布局位置的复杂布局。布局组件仅依赖于RectTransforms,并且仅影响其关联的RectTransforms的属性。它们不依赖于Graphic类,并且可以从Unity UI图形组件中独立使用。

Both Graphic and Layout components rely on the CanvasUpdateRegistry class, which is not exposed in the Unity Editor's interface. This class tracks the set of Layout components and Graphic components that must be updated, and triggers updates as needed when their associated Canvas invokes the willRenderCanvases event.
图形和布局组件都依赖于CanvasUpdateRegistry类,这不会在Unity 编辑器模式下看见。这个类追踪必须更新布局组件和图形组件的集合,并在关联的Canvas调用willRenderCanvases事件时根据需要触发更新。

The updates of Layout and Graphic components is called a rebuild. The rebuild process is discussed in further detail later in this document.
更新布局和图形组件被称为重建(rebuild)。重建过程在后面进一步讨论。

Rendering details
渲染细节

When composing user interfaces in Unity UI, keep in mind that all geometry drawn by a Canvas will be drawn in the Transparent queue. That is, geometry produced by Unity UI will always be drawn back-to-front with alpha blending. The important thing to remember from a performance standpoint is that each pixel rasterized from a polygon will be sampled, even if it is wholly covered by other, opaque polygons. On mobile devices, this high level of overdraw can rapidly exceed the fill-rate capacity of the GPU.
在Unity UI中制作用户界面时,记住,所有由Canvas画出的图形都会在Transparent队列中绘制。也就是说,Unity UI制作的几何图形,总会与alpha混合重置。从性能的角度来说,比较重要的一点是,多边形中的每一个像素都将被取样,即使它被其他不透明的多边形覆盖。在移动设备上,这种高水平的透支可以快速超过GPU的填充率容量。

The Batch building process (Canvases)
批量创建过程(画布)

The batch building process is the process whereby a Canvas combines the meshes representing its UI elements and generates the appropriate rendering commands to send to Unity’s graphics pipeline. The results of this process are cached and reused until the Canvas is marked as dirty, which occurs whenever there is a change to one of its constituent meshes.
批量创建过程,是画布结合表示其UI元素的网格,并生成合适的渲染指令,以发送给Unity 图形管道的过程。这个过程的结果会被缓存或者重复使用,直到画布被标记为dirty,这会在任一个网格发生变化时发生。

The meshes used by the Canvas are taken from the set of Canvas Renderer components attached to the Canvas but not contained in any Sub-canvas.
画布所用的网格是从附加在画布上的Canvas Renderer组件上取得的,但是不包含在任何一个子画布中。

Calculating the batches requires sorting the meshes by depth and examining them for overlaps, shared materials and so on. This operation is multi-threaded, and so its performance will generally be very different across different CPU architectures, and especially between mobile SoCs (which generally have few CPU cores) and modern desktop CPUs (which often have 4 or more cores).
计算批次,需要根据深度和检查它们的重叠,共用的材质等等来计算。这个操作是多线程的,因此不同的CPU结构,它的性能也不同,特别是移动SoC(通常有少量CPU内核)和电脑CPU(通常有4个或更多内核)。

The rebuild process (Graphics)
重建过程(图形)

The Rebuild process is where the layout and meshes of Unity UI’s C# Graphic components are recalculated. This is performed in the CanvasUpdateRegistry class. Remember, this is a C# class and its source can be found on Unity’s Bitbucket.
重建过程是重新计算Unity UI的C#Graphic组件的布局和网格的过程。这在CanvasUpdateRegistry类中执行。记住,这是一个C#类,它的源代码可以在Unity’s Bitbucket上找到。

Within CanvasUpdateRegistry, the method of interest is PerformUpdate. This method is invoked whenever a Canvas component invokes the WillRenderCanvases event. This event is called once per frame.
在CanvasUpdatedRegistry中,感兴趣的方法是PerformUpdate。每当Canvas组件调用WillRenderCanvases事件时,这个方法都会被调用。这个事件每帧都会被调用。

PerformUpdate runs a three-step process:
PerformUpdate运行的三个步骤:

      ●  Dirty Layout components are requested to rebuild their layouts, via the ICanvasElement.Rebuild method.
          标记为Dirty的布局组件需要通过ICanvasElement.Rebuild方法重建布局。

      ●  Any registered Clipping components (such as Masks) are requested to cull any clipped components. This is done via ClippingRegistry.Cull.
          任何已注册的裁剪组件(如Mask)被移除,是通过ClippingRegistry.Cull方法完成的。

      ●  Dirty Graphic components are requested to rebuild their graphical elements.
          标记为Dirty的图形组件要求重建它的图形元素。

For Layout and Graphic rebuilds, the process is split into multiple parts. Layout rebuilds run in three parts (PreLayout, Layout and PostLayout) while Graphic rebuilds run in two (PreRender and LatePreRender).
布局和图形的重建过程被分为多个部分。布局重建分为3个部分(PreLayout, Layout 和 PostLayout),图形重建分为2个部分(PreRender 和 LatePreRender)。

Layout rebuilds
布局重建

To recalculate the appropriate positions (and potentially sizes) of components contained within one or more Layout components, it is necessary to apply the Layouts in their appropriate hierarchical order. Layouts closer to the root in the GameObject hierarchy can potentially alter the positions and sizes of any Layouts that may be nested within them, and so must be calculated first.
要重新计算一个或多个布局组件中包含的合适的位置(以及大小),必须以适当的层次结构顺序应用布局。在物体的层次结构中,靠近根节点的布局可能会改变内嵌在其中任何布局的位置和大小,所以必须首先计算。

To do this, Unity UI sorts the list of dirty Layout components by their depth in the hierarchy. Items higher in the hierarchy (i.e. with fewer parent Transforms) are moved to the front of the list.
要做到这点,Unity UI通过层次结构中的深度对标记为dirty的布局组件列表进行排序。层级越高(有更少的父节点)的越靠前。

The sorted list of Layout components is then requested to rebuild their layouts; this is where the positions and sizes of UI elements controlled by Layout components are actually altered. For more details on how the positions of individual elements are affected by Layouts, see the UI Auto Layout section of the Unity Manual.
排序后的布局组件被要求重建它们的布局;这就是通过改变布局组件来控制UI元素位置和大小。有关布局如何影响各个元素位置的更多详细信息,请参阅Unity手册中UI Auto Layout部分。

Graphic rebuilds
图形重建

When Graphic components are rebuilt, Unity UI passes control to the Rebuild method of the ICanvasElement interface. Graphic implements this and runs two different rebuild steps during the PreRender stage of the Rebuild process.
当图形组件重建时,Unity UI控制ICanvasElement接口的Rebuild方法。Graphic实现了这一点,并在重建过程的PreRender阶段运行了两个不同的重建步骤。

      ●  If the vertex data has been marked as dirty (e.g. when the component’s RectTransform has changed size), then the mesh is rebuilt.
          如果顶点数据被标记为dirty(例如RectTransform组件改变了大小),则重建网格。

      ●  If the material data has been marked dirty (e.g. when the component’s material or texture has been changed), then the attached Canvas Renderer’s material will be updated.
          如果材质数据被标记dirty,(例如材质或者纹理改变了),则将更新附加的Canvas Renderer材质。

Graphic Rebuilds do not proceed through the list of Graphic components in any particular order, and do not require any sorting operations.
图形重建不会按照某个特定的顺序执行,也不需要任何排序操作。


相关链接

  1. 原文地址: https://unity3d.com/cn/learn/tutorials/topics/best-practices/fundamentals-unity-ui?playlist=30089